package com.map.app;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FocusTraversalPolicy;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import javax.swing.text.PlainDocument;

import org.apache.commons.lang.StringUtils;

import com.map.domain.AsItem;
import com.map.domain.MapData;
import com.map.home.LoadData;
import com.map.manager.ConfigManager;
import com.map.manager.SystemLogManager;
import com.map.util.Constants;
import com.map.util.LogManager;
import com.map.util.StringUtil;

public class AutoScript extends javax.swing.JFrame {

	private static final long serialVersionUID = 1L;
	private static String CONFIG_FILE = "/properties/autoscript.properties";

	private static final java.util.Properties config = new java.util.Properties();

	private static LoadData loadData = LoadData.getInstance();
	private List<AsItem> appList = null;
	private List<AsItem> productList = null;
	private List<AsItem> screenList = new ArrayList<AsItem>();
	private List<AsItem> screenPCAMList = new ArrayList<AsItem>();

	private String pid = "";
	private String contentText2Keyin = "";
	private boolean isScriptChanged  = false;
	private boolean isRefreshRunning = false;
	private boolean isRefreshAllRunning = false;
	private String selectedApplication = "";
	Process process = null;
	
	private String[] detailColNames = new String[] { "Field Name",
			"Field Value", "Row No" };

	// Initiate LogManager
	private LogManager logmanager = LogManager.getInstance(ConfigManager
			.getInstance().get("AppLogFile"));

	// Initiate SystemLog
	private SystemLogManager sysLogMgr = SystemLogManager.getInstance();

	// Script Folder
	private String appScriptPath = ConfigManager.getInstance().get("AppScriptPath");
	
	private static Dimension formDms = new Dimension(665, 660);
	private static int CBX_LEN = 200;

	private static AutoScript instance = null;

	public static AutoScript getInstance() {
		synchronized (AutoScript.class) {
			if (instance == null) {
				instance = new AutoScript();
			}
		}
		return instance;
	}
	/**
	 * Creates new form GenScripts:
	 */
	private AutoScript() {
		loadProperties();
		loadApplications();
		detectPCAM();
		initComponents();
	}

	private void loadProperties() {
		try {
			InputStream stream = this.getClass().getResourceAsStream(
					CONFIG_FILE);
			if (stream != null)
				config.load(stream);
			else
				throw new Exception("Input Stream is null");
			
		} catch (Exception e) {
			sysLogMgr.logError(e);
			e.printStackTrace();
		}
	}

	private void loadApplications() {
		try {

			// check database connection is ok or not?
			String res = loadData.checkConnection();
			if (StringUtil.isEmpty(res)) {
				appList = loadData.listApplications();	
			}
			
			if (appList == null) {
				appList = new ArrayList<AsItem>();
			}
			appList.add(0, new AsItem(COMBOX_SEL_APP, null));
		} catch (Exception e) {
			sysLogMgr.logError(e);
			e.printStackTrace();
		}
	}

	private void detectPCAM() {
		try {
			String line = "";
			Process p = Runtime.getRuntime().exec("tasklist.exe /v /fo csv");
			BufferedReader input = new BufferedReader(new InputStreamReader(
					p.getInputStream()));
			int count = 1;
			int showCnt = 20;
			screenPCAMList = new ArrayList<AsItem>();
			screenPCAMList.add(new AsItem(COMBOX_SEL_PCAMSCR, null));
			while ((line = input.readLine()) != null) {
				// System.out.println("Program: " + line);
				if (line != null
						&& count != 1
						&& line.toLowerCase().indexOf(config.getProperty(Constants.PCAM_DETECT_TEXT)) != -1) {
					String[] lineArray = line.split("\",\"");
					line = lineArray[8];
					//line = (line.length()<showCnt)? line: line.substring(0, showCnt)+"...";
					// No 1: process no
					screenPCAMList.add(new AsItem(line, lineArray[1]));
				}
				count++;
			}
			input.close();
		} catch (Exception e) {
			e.printStackTrace();
			sysLogMgr.logError(e);
		}
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		jPanelApplication = new javax.swing.JPanel();
		
		jComboBoxApplication = new javax.swing.JComboBox();
		jComboBoxApplication.setEditable(true);
        // get the combo boxes editor component
        JTextComponent editor = (JTextComponent) jComboBoxApplication.getEditor().getEditorComponent();
        editor.setDocument(new ShowPopup());

		jPanelProduct = new javax.swing.JPanel();
		jPanelScreen = new javax.swing.JPanel();
		jComboBoxProduct = new javax.swing.JComboBox();
		jComboBoxScreen = new javax.swing.JComboBox();
		jPanelDetailData = new javax.swing.JPanel();
		jScrollPane1 = new javax.swing.JScrollPane();
		jTableDetailData = new javax.swing.JTable();
		jPanelRealScreen = new javax.swing.JPanel();
		jPanelEditScriptScreen = new javax.swing.JPanel();
		jComboBoxRealScreen = new javax.swing.JComboBox();
		jButtonRunAllScript = new javax.swing.JButton();
		jButtonStopAllScript = new javax.swing.JButton();
		jButtonRunScript = new javax.swing.JButton();
		jButtonRefreshPCAM = new javax.swing.JButton();
		jButtonSaveScript = new javax.swing.JButton();
		jLabelName = new javax.swing.JLabel();
		jTextFieldName = new javax.swing.JTextField();
		jLabelScript = new javax.swing.JLabel();
		jTextFieldScript = new JTextArea();
		jButtonF5All = new javax.swing.JButton();
		jButtonCancel = new javax.swing.JButton();
		jButtonRemoveScript = new javax.swing.JButton();
		
		jPanelLoginArea = new javax.swing.JPanel();
		jLabelLoginId = new javax.swing.JLabel();
		jLabelLoginTime = new JLabel();
		
		setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
		setPreferredSize(formDms);

		// Application List
		jPanelApplication.setBorder(javax.swing.BorderFactory
				.createTitledBorder(config
						.getProperty(Constants.COMBOX_TIT_APP)));

		jComboBoxApplication.setModel(new javax.swing.DefaultComboBoxModel(
				appList.toArray()));
		jComboBoxApplication.addItemListener(new ApplicationActionListener());

		javax.swing.GroupLayout jPanelApplicationLayout = new javax.swing.GroupLayout(
				jPanelApplication);
		jPanelApplication.setLayout(jPanelApplicationLayout);
		jPanelApplicationLayout.setHorizontalGroup(jPanelApplicationLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						jPanelApplicationLayout
								.createSequentialGroup()
								.addContainerGap()
								.addComponent(jComboBoxApplication,
										javax.swing.GroupLayout.PREFERRED_SIZE,
										CBX_LEN,
										javax.swing.GroupLayout.PREFERRED_SIZE)
								.addContainerGap(
										javax.swing.GroupLayout.DEFAULT_SIZE,
										Short.MAX_VALUE))

		);
		jPanelApplicationLayout.setVerticalGroup(jPanelApplicationLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						jPanelApplicationLayout
								.createSequentialGroup()
								.addComponent(jComboBoxApplication,
										javax.swing.GroupLayout.PREFERRED_SIZE,
										javax.swing.GroupLayout.DEFAULT_SIZE,
										javax.swing.GroupLayout.PREFERRED_SIZE)
								.addGap(0, 5, Short.MAX_VALUE)));

		// Start Product List
		jPanelProduct.setBorder(javax.swing.BorderFactory
				.createTitledBorder(config
						.getProperty(Constants.COMBOX_TIT_PROD)));
		jComboBoxProduct.addItemListener(new ProductActionListener());

		javax.swing.GroupLayout jPanelProductLayout = new javax.swing.GroupLayout(
				jPanelProduct);
		jPanelProduct.setLayout(jPanelProductLayout);
		jPanelProductLayout.setHorizontalGroup(jPanelProductLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						jPanelProductLayout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(jPanelProductLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

						.addGroup(
								jPanelProductLayout
										.createSequentialGroup()
										.addGroup(
												jPanelProductLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.TRAILING,
																false)
														.addGroup(
																javax.swing.GroupLayout.Alignment.LEADING,
																jPanelProductLayout
																		.createSequentialGroup()
																		.addComponent(jComboBoxProduct,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				CBX_LEN,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))

																))
						.addGroup(
							jPanelProductLayout
									.createSequentialGroup()
									.addComponent(jButtonRunAllScript)
									.addComponent(jButtonStopAllScript))
							)));

		jPanelProductLayout.setVerticalGroup(jPanelProductLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						jPanelProductLayout
								.createSequentialGroup()
								.addComponent(jComboBoxProduct,
										javax.swing.GroupLayout.PREFERRED_SIZE,
										javax.swing.GroupLayout.DEFAULT_SIZE,
										javax.swing.GroupLayout.PREFERRED_SIZE)
								
								.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

								.addGroup(
										jPanelProductLayout
												.createParallelGroup(
														javax.swing.GroupLayout.Alignment.BASELINE)
												.addComponent(
														jButtonRunAllScript)
												.addComponent(
														jButtonStopAllScript)
												)));
		// End Product

		// Start Screen Data List
		jPanelScreen.setBorder(javax.swing.BorderFactory
				.createTitledBorder(config
						.getProperty(Constants.COMBOX_TIT_SCR)));
		jComboBoxScreen.addItemListener(new ScreenActionListener());

		javax.swing.GroupLayout jPanelScreenLayout = new javax.swing.GroupLayout(
				jPanelScreen);
		jPanelScreen.setLayout(jPanelScreenLayout);
		
		//S N
		jPanelScreenLayout
		.setHorizontalGroup(jPanelScreenLayout
				.createParallelGroup(
						javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						jPanelScreenLayout
								.createSequentialGroup()
								.addContainerGap()
								.addGroup(jPanelScreenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

									.addGroup(jPanelScreenLayout
																.createSequentialGroup()
																//.addGap(10, 10, 10)
																.addComponent(jButtonRunScript)
																.addGap(10, 10, 10)
																//.addComponent(jButtonRefreshPCAM)
																) 
									.addGroup(
											jPanelScreenLayout
													.createSequentialGroup()
													.addGroup(
															jPanelScreenLayout
																	.createParallelGroup(
																			javax.swing.GroupLayout.Alignment.TRAILING,
																			false)
																	.addGroup(
																			javax.swing.GroupLayout.Alignment.LEADING,
																			jPanelScreenLayout
																					.createSequentialGroup()
																					.addComponent(jComboBoxScreen,
																							javax.swing.GroupLayout.PREFERRED_SIZE,
																							CBX_LEN,
																							javax.swing.GroupLayout.PREFERRED_SIZE)
																					.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))

																			)
													.addContainerGap())
																
									)));
		jPanelScreenLayout
		.setVerticalGroup(jPanelScreenLayout
				.createParallelGroup(
						javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						jPanelScreenLayout
								.createSequentialGroup()
								.addComponent(
										jComboBoxScreen,
										javax.swing.GroupLayout.PREFERRED_SIZE,
										25,
										javax.swing.GroupLayout.PREFERRED_SIZE)

								.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

								.addGroup(
										jPanelScreenLayout
												.createParallelGroup(
														javax.swing.GroupLayout.Alignment.BASELINE)
												.addComponent(
														jButtonRunScript)
												/*.addComponent(
														jButtonRefreshPCAM,
														javax.swing.GroupLayout.PREFERRED_SIZE,
														javax.swing.GroupLayout.DEFAULT_SIZE,
														javax.swing.GroupLayout.PREFERRED_SIZE)*/
												)

								.addPreferredGap(
										javax.swing.LayoutStyle.ComponentPlacement.RELATED)			
								.addPreferredGap(
										javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
						));
		
		//E N
								
		// End Screen Data

		// Start detail
		jTableDetailData.setEnabled(true);
		jTableDetailData.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
		jTableDetailData.setModel(new javax.swing.table.DefaultTableModel(null,
				detailColNames));

		jScrollPane1.setViewportView(jTableDetailData);

		javax.swing.GroupLayout jPanelDetailDataLayout = new javax.swing.GroupLayout(
				jPanelDetailData);
		jPanelDetailData.setLayout(jPanelDetailDataLayout);

		jPanelDetailDataLayout.setHorizontalGroup(jPanelDetailDataLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
				.addGroup(
						javax.swing.GroupLayout.Alignment.LEADING,
						jPanelDetailDataLayout
								.createSequentialGroup()
								//.addContainerGap()
								.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 400, Short.MAX_VALUE))
				.addGroup(
						javax.swing.GroupLayout.Alignment.CENTER,
						jPanelDetailDataLayout
								.createSequentialGroup()
								.addComponent(jButtonRefreshPCAM)
								.addGap(10, 10, 10)
								.addComponent(jButtonF5All)
								.addGap(10, 10, 10)
								.addComponent(jButtonCancel)
							));
		jPanelDetailDataLayout.setVerticalGroup(jPanelDetailDataLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						jPanelDetailDataLayout
								.createSequentialGroup()
								.addComponent(jScrollPane1,
										javax.swing.GroupLayout.PREFERRED_SIZE,
										463,
										javax.swing.GroupLayout.PREFERRED_SIZE)
								.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
								.addGroup(
										jPanelDetailDataLayout
												.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
												.addComponent(jButtonRefreshPCAM)
												.addComponent(jButtonF5All)
												.addComponent(jButtonCancel))));
		// End detail

		// Start real screen (PCAM)
		jPanelRealScreen.setBorder(javax.swing.BorderFactory
				.createTitledBorder(COMBOX_TIT_PCAMSCR));

		// Screen PCAM List
		jComboBoxRealScreen.setModel(new javax.swing.DefaultComboBoxModel(screenPCAMList.toArray()));
		jComboBoxRealScreen.addItemListener(new RealScreenActionListener());

		jButtonRunScript.setText("Run Script");
		jButtonRunScript.addActionListener(new RunScriptListener());
		jButtonRunScript.addKeyListener(new RunScriptListener() );

		jButtonRunAllScript.setText("Run All Scripts");
		jButtonRunAllScript.addActionListener(new RunAllScriptListener());
		jButtonRunAllScript.addKeyListener(new RunAllScriptListener() );
		
		jButtonStopAllScript.setText("Cancel Run");
		jButtonStopAllScript.addActionListener(new StopAllScriptListener());
		jButtonStopAllScript.addKeyListener(new StopAllScriptListener() );
		
		jButtonRefreshPCAM.setText("Refresh Cardlink");
		jButtonRefreshPCAM.addActionListener(new RefreshPCAMListener());
		jButtonRefreshPCAM.addKeyListener(new RefreshPCAMListener() );

		javax.swing.GroupLayout jPanelRealScreenLayout = new javax.swing.GroupLayout(
				jPanelRealScreen);
		jPanelRealScreen.setLayout(jPanelRealScreenLayout);
		jPanelRealScreenLayout
				.setHorizontalGroup(jPanelRealScreenLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanelRealScreenLayout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(jPanelRealScreenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
											.addGroup(
													jPanelRealScreenLayout
															.createSequentialGroup()
															.addGroup(
																	jPanelRealScreenLayout
																			.createParallelGroup(
																					javax.swing.GroupLayout.Alignment.TRAILING,
																					false)
																			.addGroup(
																					javax.swing.GroupLayout.Alignment.LEADING,
																					jPanelRealScreenLayout
																							.createSequentialGroup()
																							.addComponent(jComboBoxRealScreen,
																									javax.swing.GroupLayout.PREFERRED_SIZE,
																									CBX_LEN,
																									CBX_LEN)
																							.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))

																					)
															.addContainerGap())
																		
											)));
		jPanelRealScreenLayout
				.setVerticalGroup(jPanelRealScreenLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanelRealScreenLayout
										.createSequentialGroup()

										.addComponent(
												jComboBoxRealScreen,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												25,
												javax.swing.GroupLayout.PREFERRED_SIZE)

										.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)			
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
								));

		
		// End real screen (PCAM)

		
		// Start Edit Script screen
		jPanelEditScriptScreen.setBorder(javax.swing.BorderFactory
				.createTitledBorder("Edit Script"));

		jLabelName.setText("Name");
		jTextFieldName.setText("");
		jLabelScript.setText("Script  ");
		
		jTextFieldScript.setLineWrap(true);
		jTextFieldScript.setWrapStyleWord(true);
		jTextFieldScript.setColumns(50);
		jTextFieldScript.setRows(2);
		scrollScriptPane = new JScrollPane(jTextFieldScript);
		scrollScriptPane.setAutoscrolls(true);
		
		javax.swing.GroupLayout jPanelEditScriptScreenLayout = new javax.swing.GroupLayout(
				jPanelEditScriptScreen);
		jPanelEditScriptScreen.setLayout(jPanelEditScriptScreenLayout);
		jPanelEditScriptScreenLayout
				.setHorizontalGroup(jPanelEditScriptScreenLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanelEditScriptScreenLayout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(jPanelEditScriptScreenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
														.addGroup(
																jPanelEditScriptScreenLayout
																		.createSequentialGroup()
																		.addGroup(
																				jPanelEditScriptScreenLayout
																						.createParallelGroup(
																								javax.swing.GroupLayout.Alignment.TRAILING,
																								false)
																						.addGroup(
																								javax.swing.GroupLayout.Alignment.LEADING,
																								jPanelEditScriptScreenLayout
																										.createSequentialGroup()
																										.addComponent(
																												jLabelScript)
																										.addPreferredGap(
																												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																										.addComponent(
																												scrollScriptPane))
																						.addGroup(
																								javax.swing.GroupLayout.Alignment.LEADING,
																								jPanelEditScriptScreenLayout
																										.createSequentialGroup()
																										.addComponent(
																												jLabelName)
																										.addPreferredGap(
																												javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
																										.addComponent(
																												jTextFieldName)
																										.addComponent(jButtonSaveScript))
																								)
																		.addContainerGap()))));
		jPanelEditScriptScreenLayout
				.setVerticalGroup(jPanelEditScriptScreenLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanelEditScriptScreenLayout
										.createSequentialGroup()
										.addContainerGap(
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)

										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup(
												jPanelEditScriptScreenLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(
																jLabelName)
														.addComponent(
																jTextFieldName,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(jButtonSaveScript)
													)		
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
										.addGroup(
												jPanelEditScriptScreenLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(
																jLabelScript)
														.addComponent(
																scrollScriptPane,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addGroup(
												jPanelEditScriptScreenLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
										)
								
								));

		jButtonSaveScript.setText("Save Script");
		jButtonSaveScript.addActionListener(new SaveScriptListener());
		jButtonSaveScript.addKeyListener(new SaveScriptListener() );
		jButtonSaveScript.setVisible(true);
		
		// End Edit Script screen
		
		jButtonF5All.setText("Refresh All");
		jButtonF5All.addActionListener(new ListenF5All());
		jButtonF5All.addKeyListener(new ListenF5All() );

		jButtonCancel.setText("Exit");
		jButtonCancel.addActionListener(new ListenCancel());
		jButtonCancel.addKeyListener(new ListenCancel() );

		jButtonRemoveScript.setText("Remove Scripts");
		jButtonRemoveScript.setVisible(false);

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
				getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						layout.createSequentialGroup()
								.addGap(5, 5, 5) // padding
								.addGroup(
										layout.createParallelGroup(
												javax.swing.GroupLayout.Alignment.LEADING)
												.addGroup(
														layout.createSequentialGroup()
																.addGroup(
																		layout.createParallelGroup(
																				javax.swing.GroupLayout.Alignment.TRAILING,
																				false)
																				.addComponent(
																						jPanelApplication,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						Short.MAX_VALUE)
																				.addComponent(
																						jPanelProduct,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						Short.MAX_VALUE)
																				.addComponent(
																						jPanelScreen,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						Short.MAX_VALUE)
																				.addComponent(
																						jPanelRealScreen,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						Short.MAX_VALUE)
																				.addComponent(
																						jPanelLoginArea,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						Short.MAX_VALUE)
																				.addGroup(
																						javax.swing.GroupLayout.Alignment.TRAILING,
																						layout.createSequentialGroup()
																								.addComponent(
																										jButtonRemoveScript,
																										javax.swing.GroupLayout.PREFERRED_SIZE,
																										116,
																										javax.swing.GroupLayout.PREFERRED_SIZE)
																								.addGap(20,
																										20,
																										20)))
																.addPreferredGap(
																		javax.swing.LayoutStyle.ComponentPlacement.RELATED,
																		63,
																		Short.MAX_VALUE)
																.addComponent(
																		jPanelDetailData,
																		javax.swing.GroupLayout.DEFAULT_SIZE,
																		javax.swing.GroupLayout.DEFAULT_SIZE,
																		javax.swing.GroupLayout.DEFAULT_SIZE)
																.addContainerGap())
												.addGroup(
														javax.swing.GroupLayout.Alignment.TRAILING,
														layout.createSequentialGroup()
																.addGap(0,
																		32,
																		Short.MAX_VALUE)
																.addGap(322,
																		322,
																		322))
																				.addComponent(
																						jPanelEditScriptScreen,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						javax.swing.GroupLayout.DEFAULT_SIZE,
																						Short.MAX_VALUE)
										
										)));
		layout.setVerticalGroup(layout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						layout.createSequentialGroup()
								.addContainerGap(
										javax.swing.GroupLayout.DEFAULT_SIZE,
										Short.MAX_VALUE)
								.addGroup(
										layout.createParallelGroup(
												javax.swing.GroupLayout.Alignment.LEADING,
												false)
												.addGroup(
														layout.createSequentialGroup()
																.addComponent(
																		jPanelApplication,
																		javax.swing.GroupLayout.PREFERRED_SIZE,
																		javax.swing.GroupLayout.DEFAULT_SIZE,
																		javax.swing.GroupLayout.PREFERRED_SIZE)
																.addPreferredGap(
																		javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																.addComponent(
																		jPanelProduct,
																		javax.swing.GroupLayout.PREFERRED_SIZE,
																		javax.swing.GroupLayout.DEFAULT_SIZE,
																		javax.swing.GroupLayout.PREFERRED_SIZE)
																.addPreferredGap(
																		javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																.addComponent(
																		jPanelScreen,
																		javax.swing.GroupLayout.PREFERRED_SIZE,
																		javax.swing.GroupLayout.DEFAULT_SIZE,
																		javax.swing.GroupLayout.PREFERRED_SIZE)
																.addPreferredGap(
																		javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																.addPreferredGap(
																		javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																.addComponent(
																		jButtonRemoveScript)
																.addGap(4, 4, 4)
																.addComponent(
																		jPanelRealScreen,
																		javax.swing.GroupLayout.PREFERRED_SIZE,
																		javax.swing.GroupLayout.DEFAULT_SIZE,
																		javax.swing.GroupLayout.PREFERRED_SIZE)
																.addComponent(
																		jPanelLoginArea,
																		javax.swing.GroupLayout.PREFERRED_SIZE,
																		javax.swing.GroupLayout.DEFAULT_SIZE,
																		javax.swing.GroupLayout.PREFERRED_SIZE)
															)
												.addComponent(
														jPanelDetailData,
														javax.swing.GroupLayout.DEFAULT_SIZE,
														javax.swing.GroupLayout.DEFAULT_SIZE,
														Short.MAX_VALUE)
												)
								.addComponent(
										jPanelEditScriptScreen,
										javax.swing.GroupLayout.PREFERRED_SIZE,
										javax.swing.GroupLayout.DEFAULT_SIZE,
										javax.swing.GroupLayout.PREFERRED_SIZE)
							)

				);

		jPanelApplication.getAccessibleContext().setAccessibleName(
				"Applications");

		

		// Start Login
		jPanelLoginArea.setBorder(javax.swing.BorderFactory.createTitledBorder(""));
		javax.swing.GroupLayout jPanelLoginLayout = new javax.swing.GroupLayout(
				jPanelLoginArea);
		jPanelLoginArea.setLayout(jPanelLoginLayout);
		jPanelLoginLayout.setHorizontalGroup(jPanelLoginLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(
						jPanelLoginLayout
								.createSequentialGroup()
								.addComponent(jLabelLoginId))
				.addGroup(
						jPanelLoginLayout
								.createSequentialGroup()
								.addComponent(jLabelLoginTime)
								.addGap(0, 5, Short.MAX_VALUE)));
		jPanelLoginLayout.setVerticalGroup(jPanelLoginLayout
				.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(

						jPanelLoginLayout
								.createSequentialGroup()
								.addContainerGap(8, Short.MAX_VALUE)
								.addComponent(jLabelLoginId)
								.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
								.addComponent(jLabelLoginTime)
								.addContainerGap(8, Short.MAX_VALUE))
						);
		// End Login
		
		
		pack();
		setResizable(false);
		setLocationRelativeTo(null); // *** this will center your app ***
		focusTraversalPolicy = new MyFocusTraversalPolicy();
		setFocusTraversalPolicy(focusTraversalPolicy);
		setTitle(config.getProperty("form.title"));
		
		addWindowListener(new WindowAdapter() {
		      public void windowClosing(WindowEvent e) {
		        jButtonCancel.doClick();
		      }
		});
		
	}// </editor-fold>

	/**
	 * @param args
	 *            the command line arguments
	 */
	public void start(final String loginId) {
		System.out.println("AutoScript:start");
		/*
		 * Set the Nimbus look and feel
		 */
		try {
			for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager
					.getInstalledLookAndFeels()) {
				if ("Nimbus".equals(info.getName())) {
					javax.swing.UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (ClassNotFoundException ex) {
			java.util.logging.Logger.getLogger(AutoScript.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		} catch (InstantiationException ex) {
			java.util.logging.Logger.getLogger(AutoScript.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		} catch (IllegalAccessException ex) {
			java.util.logging.Logger.getLogger(AutoScript.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		} catch (javax.swing.UnsupportedLookAndFeelException ex) {
			java.util.logging.Logger.getLogger(AutoScript.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		}
		// </editor-fold>

		/*
		 * Create and display the form
		 */
		final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
		java.awt.EventQueue.invokeLater(new Runnable() {

			public void run() {
				getInstance().setVisible(true);
				jLabelLoginId.setText("Login as " + loginId);
				jLabelLoginTime.setText(dateFormat.format(new Date()));
			}
		});
	}

	// Variables declaration
	private javax.swing.JButton jButtonRunScript;
	private javax.swing.JButton jButtonRunAllScript;
	private javax.swing.JButton jButtonStopAllScript;
	private javax.swing.JButton jButtonRefreshPCAM;
	private javax.swing.JButton jButtonSaveScript;
	private javax.swing.JButton jButtonF5All;
	private javax.swing.JButton jButtonCancel;
	private javax.swing.JButton jButtonRemoveScript;

	private javax.swing.JComboBox jComboBoxApplication;
	private JTextComponent editor;
	private javax.swing.JComboBox jComboBoxProduct;
	private javax.swing.JComboBox jComboBoxScreen;
	private javax.swing.JComboBox jComboBoxRealScreen;

	private javax.swing.JLabel jLabelName;
	private javax.swing.JLabel jLabelScript;

	private javax.swing.JPanel jPanelApplication;
	private javax.swing.JPanel jPanelProduct;
	private javax.swing.JPanel jPanelScreen;
	private javax.swing.JPanel jPanelDetailData;
	private javax.swing.JPanel jPanelRealScreen;
	private javax.swing.JPanel jPanelEditScriptScreen;
	private javax.swing.JScrollPane jScrollPane1;
	private javax.swing.JTable jTableDetailData;
	private javax.swing.JTextField jTextFieldName;
	private JTextArea jTextFieldScript;
	private JScrollPane scrollScriptPane; 
	
	private javax.swing.JPanel jPanelLoginArea;
	private javax.swing.JLabel jLabelLoginId;
	private javax.swing.JLabel jLabelLoginTime;
	
	protected MyFocusTraversalPolicy focusTraversalPolicy;
	// End of variables declaration

	// Start Listener
	public class ApplicationActionListener implements ItemListener {
		public void itemStateChanged(ItemEvent e) {
			try {
				if (e.getStateChange() == ItemEvent.DESELECTED) {
				}
				if (e.getStateChange() == ItemEvent.SELECTED) {
					
					//xxx
					Object selectedItem = jComboBoxApplication.getModel().getSelectedItem();
					//System.out.println("ApplicationActionListener " + selectedItem);
					
					Object appItem = jComboBoxApplication.getSelectedItem();
					
					if (!(appItem instanceof AsItem)) {
						editor.getDocument().remove(0, editor.getDocument().getLength());
						editor.getDocument().insertString(0, selectedApplication, null);
						appItem = jComboBoxApplication.getSelectedItem();
					}

					if (appItem instanceof AsItem) {
						loadProductsByApp();
						jComboBoxProduct.setModel(new javax.swing.DefaultComboBoxModel(productList.toArray()));
	
						// reset screen
						screenList = new ArrayList<AsItem>();
						screenList.add(0, new AsItem(config.getProperty(Constants.COMBOX_SEL_SCR), null));
						jComboBoxScreen.setModel(new javax.swing.DefaultComboBoxModel(screenList.toArray()));
	
						// reset file
						jTextFieldName.setText("");
						jTextFieldScript.setText("");
		
						// reset datagrid
						jTableDetailData.setModel(new javax.swing.table.DefaultTableModel(null, detailColNames));
						
						// reset script
					contentText2Keyin = "";
					}
				} else {
					// reset product
					productList = new ArrayList<AsItem>();
					productList.add(0, new AsItem(config.getProperty(Constants.COMBOX_SEL_PROD), null));
					jComboBoxProduct.setModel(new javax.swing.DefaultComboBoxModel(productList.toArray()));

					// reset screen
					screenList = new ArrayList<AsItem>();
					screenList.add(0, new AsItem(config.getProperty(Constants.COMBOX_SEL_SCR), null));
					jComboBoxScreen.setModel(new javax.swing.DefaultComboBoxModel(screenList.toArray()));
				}
			} catch (Exception ex) {
				ex.printStackTrace();
				sysLogMgr.logError(ex);
				JOptionPane.showMessageDialog(getContentPane(), "Got problem!!! \n\nDetail: "+ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
			}
		}
	}
	private void loadProductsByApp() {
		AsItem item = (AsItem) jComboBoxApplication.getSelectedItem();
		if (item != null && !StringUtil.isEmpty(item.getValue())) {
			productList = loadData.listProductsByApplication(item
					.getValue());
		} else {
			productList = null;
		}
		if (productList == null)
			productList = new ArrayList<AsItem>();
		productList.add(0,new AsItem(config.getProperty(Constants.COMBOX_SEL_PROD), null));
	}

	public class ProductActionListener implements ItemListener {
		public void itemStateChanged(ItemEvent e) {
			try {
				if (e.getStateChange() == ItemEvent.SELECTED) {
					loadScreensByAppAndProduct();
					jComboBoxScreen.setModel(new javax.swing.DefaultComboBoxModel(
							screenList.toArray()));
					// reset file
					jTextFieldName.setText("");
					jTextFieldScript.setText("");
	
					// reset datagrid
					jTableDetailData.setModel(new javax.swing.table.DefaultTableModel(null, detailColNames));
					
					// reset script
					contentText2Keyin = "";
				}
			} catch (Exception ex) {
				ex.printStackTrace();
				sysLogMgr.logError(ex);
				JOptionPane.showMessageDialog(getContentPane(), "Got problem!!! \n\nDetail: "+ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
			}
		}
	}

	private void loadScreensByAppAndProduct() {
		AsItem itemApp = (AsItem) jComboBoxApplication.getSelectedItem();
		AsItem itemProd = (AsItem) jComboBoxProduct.getSelectedItem();
		if (itemApp != null && !StringUtil.isEmpty(itemApp.getValue())
				&& itemProd != null
				&& !StringUtil.isEmpty(itemProd.getValue())) {
			screenList = loadData.listScreensByProductAndApplication(
					itemApp.getValue(), itemProd.getValue());
		} else {
			screenList = null;
		}
		if (screenList == null)
			screenList = new ArrayList<AsItem>();
		screenList.add(0,
				new AsItem(config.getProperty(Constants.COMBOX_SEL_SCR),
						null));
	}

	/**
	 * Select screen: get detail data base on Application, Product, Screen
	 */
	public class ScreenActionListener implements ItemListener {
		public void itemStateChanged(ItemEvent e) {
			if (e.getStateChange() == ItemEvent.SELECTED) {
				buildScriptToKeyinPCAM();
			}
		}
	}
	
	private void buildScriptToKeyinPCAM() {
		buildScriptToKeyinPCAM(null, false); // get from screen combobox and need to show data in datagrid
	}
	private void buildScriptToKeyinPCAM(AsItem itemScr, boolean isAllScreen) {
		try {
			AsItem itemApp = (AsItem) jComboBoxApplication.getSelectedItem();
			AsItem itemProd = (AsItem) jComboBoxProduct.getSelectedItem();
			if (itemScr == null) {
				itemScr = (AsItem) jComboBoxScreen.getSelectedItem();
			}

			MapData mapData = loadData.getDetailData(itemApp.getValue(),
					itemProd.getValue(), itemScr.getValue());
			if (mapData != null) {
				// Build the message to key in here
				String[] result = loadData.buildScriptToSend(
						itemApp.getValue(), itemProd.getValue(), itemScr.getValue(), mapData.getContentTextArray());

				contentText2Keyin = result[1];
				//System.out.println(contentText2Keyin);
				
				// reset file
				//jTextFieldName.setText("");
				//jTextFieldScript.setText("");

				if (!isAllScreen) {
					// show in datagrid
					jTableDetailData.setModel(new javax.swing.table.DefaultTableModel(
									loadData.buildDataGrid(itemScr.getValue(), mapData.getContentTextArray()), detailColNames));
					
					// show script
					jTextFieldName.setText(itemScr.getValue() + "_" + itemProd.getValue() + ".txt");
					jTextFieldScript.setText(result[0]);
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			sysLogMgr.logError(ex);
			JOptionPane.showMessageDialog(getContentPane(), "Got problem!!! \n\nDetail: "+ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
		}
	}

	/**
	 * select PCAM screen
	 */
	public class RealScreenActionListener implements ItemListener {
		public void itemStateChanged(ItemEvent e) {
			if (e.getStateChange() == ItemEvent.SELECTED) {
				AsItem item = (AsItem) jComboBoxRealScreen.getSelectedItem();
				pid = item.getValue();
			}
		}
	}

	/**
	 * Send Script to PCAM
	 */
	public class RunScriptListener implements ActionListener, KeyListener  {
		public void actionPerformed(ActionEvent event) {
			sendScript();
		}
		
		public void keyTyped(KeyEvent e) {}

		public void keyPressed(KeyEvent e) {
			if (e.getKeyCode()==KeyEvent.VK_ENTER){
				sendScript();
			}
		}

		public void keyReleased(KeyEvent e) {}
	}

	public class RunAllScriptListener implements ActionListener, KeyListener  {
		public void actionPerformed(ActionEvent event) {
			pressSendAll();
		}
		
		public void keyTyped(KeyEvent e) {}

		public void keyPressed(KeyEvent e) {
			if (e.getKeyCode()==KeyEvent.VK_ENTER){
				pressSendAll();
			}
		}

		public void keyReleased(KeyEvent e) {}

	}

	private void pressSendAll() {
		if (!keyining) {
			keyInThread = new KeyInThread ();
			keyInThread.start ();
		}
	}
	
	/**
	 * This method is used to send all scripts (screen) in pair [Application, Product] to PCAM
	 */
	KeyInThread keyInThread = null;
	boolean keyining = false;
	class KeyInThread extends Thread {

		public void run () {
			try {
				keyining = true;
				sendAllScript();
			} catch (Exception e) {
			} finally {
				keyining = false;
			}
		}

		private void sendAllScript() {
			List<AsItem> screenListTmp = null;
			
			AsItem itemApp = (AsItem) jComboBoxApplication.getSelectedItem();
			AsItem itemProd = (AsItem) jComboBoxProduct.getSelectedItem();
			if (itemApp != null && !StringUtil.isEmpty(itemApp.getValue())
					&& itemProd != null && !StringUtil.isEmpty(itemProd.getValue())) {
				screenListTmp = loadData.listScreensByProductAndApplication(itemApp.getValue(), itemProd.getValue());
				
				if (screenListTmp != null && !screenListTmp.isEmpty()) {
					if (!StringUtil.isEmpty(pid)) {
						for (int i = 0; i < screenListTmp.size(); i++) {
							if (keyining) {
								// fist time need to activate PCAM
								isScriptChanged = true; // inform to change script
								//System.out.println("Key In Screen: " + screenListTmp.get(i).getValue());
								sendScript((i==0)?true:false, screenListTmp.get(i), true);
							}
						}
					} else {
						JOptionPane.showMessageDialog(getContentPane(), SELECT_PCAM_SCR);
						jComboBoxRealScreen.requestFocus();
					}
				}
			} else {
				if (itemApp == null || itemApp.getValue() == null) {
					JOptionPane.showMessageDialog(getContentPane(), "You have to choose Application");
				} else if (itemProd == null || itemProd.getValue() == null) {
					JOptionPane.showMessageDialog(getContentPane(), "You have to choose Product");
				}
			}
		}
	}

	/**
	 * Default parameters
	 */
	private void sendScript() {
		sendScript(true, null, false);
	}
	/**
	 * This method is used to send script to PCAM
	 */
	private void sendScript(boolean activeApp, AsItem itemScreen, boolean isAllScreen) {
		try {
			
			if (isScriptChanged) {
				buildScriptToKeyinPCAM(itemScreen, isAllScreen);
				isScriptChanged = false;
			}

			if (!StringUtil.isEmpty(contentText2Keyin)) {
				if (!StringUtil.isEmpty(pid)) {

					StringBuilder vbs = new StringBuilder("Set WshShell = WScript.CreateObject(\"WScript.Shell\")\n");
					if (activeApp) {
						vbs.append("WshShell.AppActivate " + pid + ", 9\n");
					}
					vbs.append("WScript.Sleep 1\n" + contentText2Keyin);
							
					//System.out.println(contentText2Keyin);
					//System.out.println(vbs);
					logmanager.logMsg("vbs:" + vbs);
					
					File file = File.createTempFile("PrintDialog", ".vbs");
					file.deleteOnExit();
					FileWriter fw = new java.io.FileWriter(file);
					fw.write(vbs.toString());
					fw.close();

					process = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
					process.waitFor();
				} else {
					JOptionPane.showMessageDialog(getContentPane(), SELECT_PCAM_SCR);
					jComboBoxRealScreen.requestFocus();
				}
			} else {
				AsItem itemApp = 	(AsItem) jComboBoxApplication.getSelectedItem();
				AsItem itemProd = 	(AsItem) jComboBoxProduct.getSelectedItem();
				AsItem itemScr = 	(AsItem) jComboBoxScreen.getSelectedItem();

				if (itemApp == null || itemApp.getValue() == null) {
					JOptionPane.showMessageDialog(getContentPane(), "You have to choose Application");
					jComboBoxApplication.requestFocus();
				} else if (itemProd == null || itemProd.getValue() == null) {
					JOptionPane.showMessageDialog(getContentPane(), "You have to choose Product");
					jComboBoxProduct.requestFocus();
				} else if (itemScr == null || itemScr.getValue() == null) {
					JOptionPane.showMessageDialog(getContentPane(), "You have to choose Screen Type");
					jComboBoxScreen.requestFocus();
				} else {
					JOptionPane.showMessageDialog(getContentPane(), "Something wrong with script file, please check it!");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			sysLogMgr.logError(e);
			JOptionPane.showMessageDialog(getContentPane(), "System problem!!! \n\nDetail: "+e.getMessage());
		}
	}

	public class StopAllScriptListener implements ActionListener, KeyListener  {
		public void actionPerformed(ActionEvent event) {
			stopAllScript();
		}
		
		public void keyTyped(KeyEvent e) {}

		public void keyPressed(KeyEvent e) {
			if (e.getKeyCode()==KeyEvent.VK_ENTER){
				stopAllScript();
			}
		}

		public void keyReleased(KeyEvent e) {}

	}
	
	private void stopAllScript() {
		if (process != null) {
			process.destroy();
		}
		keyining = false;
	}

	public class SaveScriptListener implements ActionListener, KeyListener  {
		public void actionPerformed(ActionEvent event) {
			saveScript();
		}
		public void keyTyped(KeyEvent e) {}

		public void keyPressed(KeyEvent e) {
			if (e.getKeyCode()==KeyEvent.VK_ENTER){
				saveScript();
			}
		}

		public void keyReleased(KeyEvent e) {}
		
		private void saveScript() {
			try {
				
				String fileName = jTextFieldName.getText();
				String filePath = appScriptPath + File.separator + fileName;
				if (StringUtils.isEmpty(fileName)) { // check file name is empty or not?
					JOptionPane.showMessageDialog(getContentPane(), "You have to input file name");
				} else {
					if (fileName.indexOf('.') == -1) {
						fileName += ".txt";
					}
					
					File file = new File(filePath);
					// check file is existed or not?
					int dialogResult = JOptionPane.YES_OPTION;
					if (file.exists()) {
						int dialogButton = JOptionPane.YES_NO_OPTION;
						dialogResult = JOptionPane.showConfirmDialog (null, config.getProperty("form.msg.file.overwrite"),"Warning",dialogButton);
					}
					// save to file
					if(dialogResult == JOptionPane.YES_OPTION) {						
						if (file.exists()) {
							file.delete();
						}
						if (file.createNewFile()) {
							FileWriter fw = new FileWriter(file.getAbsoluteFile());
							BufferedWriter bw = new BufferedWriter(fw);
							bw.write(jTextFieldScript.getText());
							bw.close();
							fw.close();
							JOptionPane.showMessageDialog(getContentPane(), "Script has been saved successfully");
							isScriptChanged = true; // mark as script changed
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				sysLogMgr.logError(e);
				JOptionPane.showMessageDialog(getContentPane(), "An error occurs while save script file");
			}
		}
	}

	public class ListenCancel implements ActionListener, KeyListener {
		public void actionPerformed(ActionEvent e) {
			cancel();
		}
		public void keyTyped(KeyEvent e) {}
		public void keyPressed(KeyEvent e) {
			if (e.getKeyCode()==KeyEvent.VK_ENTER){
				cancel();
			}
		}
		public void keyReleased(KeyEvent e) {}
		
		private void cancel() {
			int dialogResult = JOptionPane.YES_OPTION;
			dialogResult = JOptionPane.showConfirmDialog (null, "Do you want to exit","Confirm", JOptionPane.YES_OPTION);
			if(dialogResult == JOptionPane.YES_OPTION) {
				System.exit(0);
			}
		}
	}

	public class ListenF5All implements ActionListener, KeyListener {
		public void actionPerformed(ActionEvent e) {
			refreshAll();
		}
		public void keyTyped(KeyEvent e) {}
		public void keyPressed(KeyEvent e) {
			if (e.getKeyCode()==KeyEvent.VK_ENTER){
				refreshAll();
			}
		}
		public void keyReleased(KeyEvent e) {}
	}
	
	public class MyFocusTraversalPolicy extends FocusTraversalPolicy {
		public Component getComponentAfter(Container focusCycleRoot,
				Component aComponent) {
			if (aComponent.equals(jComboBoxApplication) || aComponent.equals(editor))
				return jComboBoxProduct;
			else if (aComponent.equals(jComboBoxProduct))
				return jButtonRunAllScript;
			else if (aComponent.equals(jButtonRunAllScript))
				return jButtonStopAllScript;
			else if (aComponent.equals(jButtonStopAllScript))
				return jComboBoxScreen;
			else if (aComponent.equals(jComboBoxScreen))
				return jButtonRunScript;
			else if (aComponent.equals(jButtonRunScript))
				return jComboBoxRealScreen;
			else if (aComponent.equals(jComboBoxRealScreen))
				return jButtonRefreshPCAM;
			else if (aComponent.equals(jButtonRefreshPCAM))
				return jButtonF5All;
			else if (aComponent.equals(jButtonF5All))
				return jButtonCancel;
			else if (aComponent.equals(jButtonCancel))
				return jTextFieldName;
			else if (aComponent.equals(jTextFieldName))
				return jTextFieldScript;
			else if (aComponent.equals(jTextFieldScript))
				return jButtonSaveScript;
			else if (aComponent.equals(jButtonSaveScript))
				return editor;
			else
				return editor;
		}

		public Component getComponentBefore(Container focusCycleRoot,
				Component aComponent) {
			if (aComponent.equals(jButtonSaveScript))
				return jTextFieldScript;
			else if (aComponent.equals(jTextFieldScript))
				return jTextFieldName;
			else if (aComponent.equals(jTextFieldName))
				return jButtonCancel;
			else if (aComponent.equals(jButtonCancel))
				return jButtonF5All;
			else if (aComponent.equals(jButtonF5All))
				return jButtonRefreshPCAM;
			else if (aComponent.equals(jButtonRefreshPCAM))
				return jComboBoxRealScreen;
			else if (aComponent.equals(jComboBoxRealScreen))
				return jButtonRunScript;
			else if (aComponent.equals(jButtonRunScript))
				return jComboBoxScreen;
			else if (aComponent.equals(jComboBoxScreen))
				return jButtonStopAllScript;
			else if (aComponent.equals(jButtonStopAllScript))
				return jButtonRunAllScript;
			else if (aComponent.equals(jButtonRunAllScript))
				return jComboBoxProduct;
			else if (aComponent.equals(jComboBoxProduct))
				return editor;
			else if (aComponent.equals(jComboBoxApplication) || aComponent.equals(editor))
				return jButtonSaveScript;
			else
				return editor;
		}

		public Component getDefaultComponent(Container focusCycleRoot) {
			return jComboBoxApplication;
		}

		public Component getFirstComponent(Container focusCycleRoot) {
			return jComboBoxApplication;
		}

		public Component getLastComponent(Container focusCycleRoot) {
			return jButtonRunScript;
		}
	}

	/**
	 * Refresh PCAM
	 *
	 */
	public class RefreshPCAMListener implements ActionListener, KeyListener  {
		public void actionPerformed(ActionEvent event) {
			try {
				if (!isRefreshRunning) {
					isRefreshRunning = true;
					refreshPCAM();
				}
			} catch (Exception ex) {
				ex.printStackTrace();
				sysLogMgr.logError(ex);
			} finally {
				isRefreshRunning = false;
			}
		}
		
		public void keyTyped(KeyEvent e) {}

		public void keyPressed(KeyEvent e) {
			if (e.getKeyCode()==KeyEvent.VK_ENTER){
				try {
					if (!isRefreshRunning) {
						isRefreshRunning = true;
						refreshPCAM();
					}
				} catch (Exception ex) {
					ex.printStackTrace();
					sysLogMgr.logError(ex);
				} finally {
					isRefreshRunning = false;
				}
			}
		}

		public void keyReleased(KeyEvent e) {}
		
	}

	private void refreshPCAM() {
		try {
			detectPCAM();
			jComboBoxRealScreen.setModel(new javax.swing.DefaultComboBoxModel(screenPCAMList.toArray()));
			setSelectedIndex(jComboBoxRealScreen, pid, screenPCAMList);
		} catch (Exception e) {
			e.printStackTrace();
			sysLogMgr.logError(e);
		}
	}

	private void refreshAPP() {
		try {
			AsItem itemApp = (AsItem) jComboBoxApplication.getSelectedItem();			
			loadApplications();
			jComboBoxApplication.setModel(new javax.swing.DefaultComboBoxModel(appList.toArray()));
			if (itemApp != null && !StringUtil.isEmpty(itemApp.getValue())) {
				setSelectedIndex(jComboBoxApplication, itemApp.getValue(), appList);
			}

		} catch (Exception e) {
			e.printStackTrace();
			sysLogMgr.logError(e);
		}
	}
	
	private void refreshProduct(String currentValue) {
		try {
			loadProductsByApp();
			jComboBoxProduct.setModel(new javax.swing.DefaultComboBoxModel(productList.toArray()));
			if (!StringUtil.isEmpty(currentValue)) {
				setSelectedIndex(jComboBoxProduct, currentValue, productList);
			}

		} catch (Exception e) {
			e.printStackTrace();
			sysLogMgr.logError(e);
		}
	}
	
	private void refreshScreen(String currentValue) {
		try {
					
			loadScreensByAppAndProduct();
			jComboBoxScreen.setModel(new javax.swing.DefaultComboBoxModel(screenList.toArray()));
			if (!StringUtil.isEmpty(currentValue)) {
				setSelectedIndex(jComboBoxScreen, currentValue, screenList);
			}

		} catch (Exception e) {
			e.printStackTrace();
			sysLogMgr.logError(e);
		}
	}
	
	private void refreshAll() {
		
		try {
			if (!isRefreshAllRunning) {
				isRefreshAllRunning = true;
				
				AsItem iP = (AsItem) jComboBoxProduct.getSelectedItem();
				AsItem iS = (AsItem) jComboBoxScreen.getSelectedItem();	
				
				refreshAPP();
				refreshProduct((iP != null)? iP.getValue(): null);
				refreshScreen((iS != null)? iS.getValue(): null);
				refreshPCAM();
				
			}
		} catch (Exception e) {
			e.printStackTrace();
			sysLogMgr.logError(e);
		} finally {
			isRefreshAllRunning = false;
		}
			
	}
	
	private void setSelectedIndex(JComboBox combox, String value, List<AsItem> listItem) {
		int index = 0;
		if (listItem != null && !listItem.isEmpty()) {
			for (int i = 0; i < listItem.size(); i++) {
				if (!StringUtil.isEmpty(value) && value.equals(listItem.get(i).getValue())) {
					index = i;
					break;
				}
			}
		}
		combox.setSelectedIndex(index);
	}

	public class ShowPopup extends PlainDocument {
		private static final long serialVersionUID = 1L;
	    // flag to indicate if setSelectedItem has been called
	    // subsequent calls to remove/insertString should be ignored
	    boolean selecting=false;
	    
	    public ShowPopup() {
	        editor = (JTextComponent) jComboBoxApplication.getEditor().getEditorComponent();
	        jComboBoxApplication.addActionListener(new ActionListener() {
	            public void actionPerformed(ActionEvent e) {
	                if (!selecting) highlightCompletedText(0, -1);
	            }
	        });
	        editor.addKeyListener(new KeyAdapter() {
	            public void keyPressed(KeyEvent e) {
	                if (jComboBoxApplication.isDisplayable()) jComboBoxApplication.setPopupVisible(true);
	            }
	        });
	    }
	    
	    public void remove(int offs, int len) throws BadLocationException {
	        // return immediately when selecting an item
	        if (selecting) return;
	        super.remove(offs, len);
	    }
	    
	    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
	        // return immediately when selecting an item
	        if (selecting) return;
	        // insert the string into the document
	        super.insertString(offs, str, a);
	        // lookup and select a matching item
	        String pattern = getText(0, getLength());
	        Object item = lookupItem(pattern);
	        int start = 0;
	        int end   = 0;
	        if (item != null) {
	            setSelectedItem(item);
	            AsItem it = (AsItem)item;
	            start = it.getValue().toUpperCase().indexOf(pattern.toUpperCase());
	            end   = start + pattern.length();
	        } else {
	            // keep old item selected if there is no match
	            item = jComboBoxApplication.getSelectedItem();
	            // imitate no insert (later on offs will be incremented by str.length(): selection won't move forward)
	            offs = offs-str.length();
	            // provide feedback to the user that his input has been received but can not be accepted
	            jComboBoxApplication.getToolkit();//.beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
	        }
	        setText(item.toString());
	        // select the completed part
	        //System.out.println(start + "         " + end);
	        highlightCompletedText(start, end);
	    }
	    
	    private void setText(String text) throws BadLocationException {
	        // remove all text and insert the completed string
	        //super.remove(0, getLength());
	        //super.insertString(0, text, null);
	    }
	    
	    private void highlightCompletedText(int start, int end) {
	    	if (end < 0) { 
	    		end = getLength();
	    	}
	        //editor.setSelectionStart(start);
	        //editor.setSelectionEnd(end);
	    }
	    
	    private void setSelectedItem(Object item) {
	        selecting = true;
	        jComboBoxApplication.getModel().setSelectedItem(item);
	        //System.out.println("XXX: " + jComboBoxApplication.getModel().getSelectedItem());
	        selectedApplication = item.toString();
	        selecting = false;
	    }
	    
	    private Object lookupItem(String pattern) {
	        Object selectedItem = jComboBoxApplication.getModel().getSelectedItem();
	        // only search for a different item if the currently selected does not match
	        if (selectedItem != null && (selectedItem instanceof AsItem) && startsWithIgnoreCase(selectedItem.toString(), pattern)) {
	            return selectedItem;
	        } else {
	            // iterate over all items
	            for (int i=0, n=jComboBoxApplication.getModel().getSize(); i < n; i++) {
	                Object currentItem = jComboBoxApplication.getModel().getElementAt(i);
	                // current item starts with the pattern?
	                if (startsWithIgnoreCase(currentItem.toString(), pattern)) {
	                    return currentItem;
	                }
	            }
	        }
	        // no item starts with the pattern => return null
	        return null;
	    }
	    
	    // checks if str1 starts with str2 - ignores case
	    private boolean startsWithIgnoreCase(String str1, String str2) {
	    	if (COMBOX_SEL_APP.equals(str1)) {
	    		return false;
	    	}
	    	int res = str1.toUpperCase().indexOf(str2.toUpperCase());
	        return res > -1;
	    }
	    
	}
	
	// message
	private final static String COMBOX_TIT_PCAMSCR = "Cardlink Window";
	private final static String COMBOX_SEL_PCAMSCR = "-- select cardlink window --";
	//private final static String COMBOX_SEL_APP     = "-- select application --";
	private final static String COMBOX_SEL_APP     = "";
	
	// alert
	private final static String SELECT_PCAM_SCR = "You have to choose one Cardlink Window!";

}